package ninth.同步与死锁.使用同步解决问题;

/**
 * 首先需要知道的是“使用代码块解决以上的问题”这个例子没有意义
 * <p>
 * 首先，“死锁”是一种需要回避的代码，并且在多线程的开发中，死锁都是通过大量测试之后才可以被检测出来的一种程序非法状态。
 * 下面这个例子只是为了讲解死锁产生时的状态，本身不具备任何的参考性，即便对代码不理解也没有任何影响。
 */
class Zhangsan {
    public void say() {
        System.out.println("张三对李四说:\"你给我画,我就把书给你 \"。");
    }

    public void get() {
        System.out.println("张三得到画了。");
    }

}

class Lisi {
    public void say() {
        System.out.println("李四对张三说：\"你给我书，我就把画给你\"。");
    }

    public void get() {
        System.out.println("李四得到书了。");
    }
}

public class ThreadDeadLock implements Runnable {   // 定义多线程类
    private static Zhangsan zs = new Zhangsan();
    private static Lisi ls = new Lisi();
    private boolean flag = false;

    @Override
    public void run() {
        if (flag) {
            synchronized (zs) {
                zs.say();
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (ls) {
                    zs.get();
                }
            }

        } else {
            synchronized (ls) {
                ls.say();
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (zs) {
                    ls.get();
                }
            }
        }
    }

    public static void main(String[] args) {
        ThreadDeadLock t1 = new ThreadDeadLock();// 实例化线程对象
        ThreadDeadLock t2 = new ThreadDeadLock();// 实例化线程对象
        t1.flag = true;// 设置标记
        t2.flag = false;
        Thread thA = new Thread(t1);// 实例化THread类对象
        Thread thB = new Thread(t2);// 实例化THread类对象
        thA.start();// 启动线程
        thB.start();
    }
}
/**
 * 两个线程都在等待对方的执行完成，这样程序就无法向下之心给，造成了死锁
 *
 * 注意：  同步与死锁的使用
 * 记住：多个线程共享同一资源时需要同步，以保证资源操作的完整性，但是过多的同步就有可能产生死锁。
 *
 * 面试题：请解释多个线程访问同一资源时需要考虑哪些情况？有可能带来哪些问题？
 * 答：
 * ①多个线程访问同一资源时，考虑数据操作的安全性问题，一定要使用同步操作。同步有以下两种操作模式：
 *  1.同步代码块：synchronized(锁定对象){代码}
 *  2.同步方法： public synchronized 返回值 方法名称() {代码}
 * ②过多的同步操作有可能带来死锁问题，导致程序进入停止状态
 *
 */

/*
D:\WorkSpaces\Java\jdk-21\bin\java.exe "-javaagent:D:\Software\IntelliJ IDEA\IntelliJ IDEA 2023.3.2\lib\idea_rt.jar=59881:D:\Software\IntelliJ IDEA\IntelliJ IDEA 2023.3.2\bin" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath D:\WorkSpaces\JavaDevelopBase_start_329\out\production\JavaDevelopBase_start_329 ninth.同步与死锁.使用同步解决问题.ThreadDeadLock
李四对张三说："你给我书，我就把画给你"。
张三对李四说:"你给我画,我就把书给你 "。

[线程进入死锁状态，程序进入死锁状态]







 */